﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Http.Filters;
using System.Web.Http.Controllers;
using System.Web;
using System.Net.Http;
using System.Net;
using System.Web.Http;
using System.Collections.Specialized;
using System.IO;

namespace HttpController.Filters
{
    public class AccessTokenValidator
    {
        public bool ValidateToken(string token, string[] scope)
        {
            // replace this logic with dataBase access to table with tokens
            if (token != "someToken")
            {
                return false;
            }
            return true;
        }
    }

    /// <summary>
    /// http://blog.developers.ba/asp-net-web-api-authorization-using-tokens/
    /// </summary>
    public class RequireAuthorizationAttribute : ActionFilterAttribute
    {
        public string Scope { get; set; }

        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            if (actionContext.Request.Method == HttpMethod.Get)
            {
                string[] scope = null;
                if (!string.IsNullOrEmpty(Scope))
                {
                    scope = Scope.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                }

                string query = actionContext.Request.RequestUri.Query;
                string accessToken = HttpUtility.ParseQueryString(query).Get("accessToken");

                if (accessToken != null)
                {
                    AccessTokenValidator accessTokenValidator = new AccessTokenValidator();
                    bool validToken = accessTokenValidator.ValidateToken(accessToken, scope);

                    if (!validToken)
                    {
                        var response = new HttpResponseMessage
                        {
                            Content =
                                new StringContent("This token is not valid, please refresh token or obtain valid token!"),
                            StatusCode = HttpStatusCode.Unauthorized
                        };
                        throw new HttpResponseException(response);
                    }
                }
                else
                {
                    //var response = new HttpResponseMessage
                    //{
                    //    Content =
                    //        new StringContent("You must supply valid token to access method!"),
                    //    StatusCode = HttpStatusCode.Unauthorized
                    //};
                    //throw new HttpResponseException(response);
                }
            }
            else
            {
                using (var stream = new MemoryStream())
                {
                    var context = (HttpContextBase)actionContext.Request.Properties["MS_HttpContext"];
                    context.Request.InputStream.Seek(0, SeekOrigin.Begin);
                    context.Request.InputStream.CopyTo(stream);
                    string requestBody = Encoding.UTF8.GetString(stream.ToArray());

                    //actionContext.Request.Content = new StringContent(requestBody, Encoding.UTF8, "application/x-www-form-urlencoded");

                    if (actionContext.Request.Content.IsFormData())
                    {
                        string postvalue = requestBody;

                        //actionContext.Request.Content.LoadIntoBufferAsync().Wait();
                        //Stream inputstream = new MemoryStream();
                        //actionContext.Request.Content.CopyToAsync(inputstream);                   

                        ////System.IO.Stream inputstream = actionContext.Request.Content.ReadAsStreamAsync().Result;

                        //Encoding encoding = Encoding.UTF8;
                        //inputstream.Position = 0;
                        //string responseData = string.Empty;
                        //using (StreamReader reader = new StreamReader(inputstream, encoding))
                        //{
                        //    responseData = reader.ReadToEnd().ToString();
                        //}

                        //string postvalue = actionContext.Request.Content.ReadAsStringAsync().Result;
                        //NameValueCollection namevalues = actionContext.Request.Content.ReadAsFormDataAsync().Result;
                    }
                    else
                    {
                        string postvalue = requestBody;
                    }
                }

                /*
                 *  http://stackoverflow.com/questions/12007689/cannot-read-body-data-from-web-api-post
                 *  Stream stream = new MemoryStream();

                    request.Content.ReadAsStreamAsync().Result.CopyTo(stream);
                    stream.Seek(0,SeekOrigin.Begin);

                    // copy off the content "for later"
                    string query = new StreamReader(stream).ReadToEnd();
                    stream.Seek(0,SeekOrigin.Begin);

                    // if further processing depends on content type
                    // go ahead and grab current value
                    var contentType = request.Content.Headers.ContentType;

                    request.Content = new StreamContent(stream);
                    request.Content.Headers.ContentType = contentType;
                 */
            }

            base.OnActionExecuting(actionContext);
        }
    }
}